package com.zlc.platform.job;

import cn.hutool.core.date.DateUtil;
import com.zlc.common.common.constant.SysControlType;
import com.zlc.common.core.sys.mapper.MayanSysControlMapper;
import com.zlc.common.core.sys.model.entity.MayanSysControl;
import com.zlc.common.core.sys.model.vo.MayanSysControlVo;
import com.zlc.common.core.sys.service.MayanSysControlService;
import com.zlc.common.util.DateUtils;
import com.zlc.common.util.JsonHelper;
import com.zlc.platform.model.control.SysCache;
import com.zlc.platform.model.control.SysCpu;
import com.zlc.platform.model.control.SysThread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.lang.management.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;

/**
 * 系统监控定时任务获取
 */
@Slf4j
@Component
public class SysControlJob {

    @Autowired
    private MayanSysControlService mayanSysControlService;
    @Autowired
    private MayanSysControlMapper mayanSysControlMapper;

    /**
     * 5秒钟执行一次
     */
    @Scheduled(cron = "0/5 * * * * ?")
    public void sysControlCal(){
        //保存系统内存监控
        calCache();
        //保存系统cpu监控
        calCpu();
        //保存系统线程监控
        threadCal();
    }


    /**
     * 1分钟执行一次
     */
    @Scheduled(cron = "0 0/1 * * * ?")
    public void removeHistControl(){
        //将10分钟前的监控数据删除
        Date lastTime = DateUtils.getNextMinute(new Date(), -10);
        mayanSysControlMapper.removeHistControl(lastTime);
    }

    /**
     * 线程监控
     */
    private void threadCal(){
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();

        SysThread thread = new SysThread();
        thread.setActiveThread(threadMXBean.getThreadCount());
        thread.setPeakThreadCount(threadMXBean.getPeakThreadCount());
        thread.setTotalStartedThreadCount(threadMXBean.getTotalStartedThreadCount());

        MayanSysControlVo controlVo = new MayanSysControlVo();
        controlVo.setControlType(SysControlType.SYS_THREAD.getControlType());
        controlVo.setControlContent(JsonHelper.toJson(thread));
        mayanSysControlService.saveVo(controlVo);
    }


    /**
     * cpu监控
     */
    private void calCpu(){
        OperatingSystemMXBean osMXBean = ManagementFactory.getOperatingSystemMXBean();
        if (osMXBean instanceof com.sun.management.OperatingSystemMXBean) {
            com.sun.management.OperatingSystemMXBean sunOsMXBean =
                    (com.sun.management.OperatingSystemMXBean) osMXBean;

            SysCpu cpu = new SysCpu();
            //系统cpu使用率
            BigDecimal sysLoad = BigDecimal.valueOf(sunOsMXBean.getSystemCpuLoad() * 100).setScale(2, RoundingMode.HALF_UP);
            if(sysLoad.compareTo(BigDecimal.ZERO) <= 0){
                return;
            }
            cpu.setSysCpuLoad(sysLoad.toPlainString() + "%");
            cpu.setSysCpuLoadDouble(sysLoad.doubleValue());
            //当前进程cpu使用率 保留2位小数
            BigDecimal cpuLoad = BigDecimal.valueOf(sunOsMXBean.getProcessCpuLoad() * 100).setScale(2, RoundingMode.HALF_UP);
            cpu.setProcessCpuLoad(cpuLoad.toPlainString() + "%");
            cpu.setProcessCpuLoadDouble(cpuLoad.doubleValue());

            MayanSysControlVo controlVo = new MayanSysControlVo();
            controlVo.setControlType(SysControlType.SYS_CPU.getControlType());
            controlVo.setControlContent(JsonHelper.toJson(cpu));
            mayanSysControlService.saveVo(controlVo);
        }
    }

    /**
     * 计算生成内存监控
     */
    private void calCache(){
        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
        MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();

        long usedKb = heapMemoryUsage.getUsed() / 1024 / 1024;
        long maxKb = heapMemoryUsage.getMax() / 1024 / 1024;
        long committedKb = heapMemoryUsage.getCommitted() / 1024 / 1024;
        SysCache sysCache = new SysCache();
        sysCache.setUsed(usedKb);
        sysCache.setMax(maxKb);
        sysCache.setCommitted(committedKb);

        MayanSysControlVo controlVo = new MayanSysControlVo();
        controlVo.setControlType(SysControlType.SYS_CACHE.getControlType());
        controlVo.setControlContent(JsonHelper.toJson(sysCache));
        mayanSysControlService.saveVo(controlVo);
    }
}
